package org.xwalk.core;

import android.util.Log;
import java.io.InputStream;
import java.io.StringBufferInputStream;
import java.util.Map;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;



public class XWalkWebResourceResponse   {

    private ArrayList<Object> constructorTypes;
    private ArrayList<Object> constructorParams;
    private ReflectMethod postWrapperMethod;


    private XWalkCoreWrapper coreWrapper;
    private Object bridge;

    protected Object getBridge() {
        return bridge;
    }

    public XWalkWebResourceResponse(Object bridge) {
        this.bridge = bridge;
        reflectionInit();
    }

    /**
     * Sets the resource response's MIME type, for example &quot;text/html&quot;.
     *
     * @param mimeType The resource response's MIME type
     * @since 6.0
     */
    public void setMimeType(String mimeType) {
        try {
            setMimeTypeStringMethod.invoke(mimeType);
        } catch (UnsupportedOperationException e) {
            if (coreWrapper == null) {
                throw new RuntimeException("Crosswalk's APIs are not ready yet");
            } else {
                XWalkCoreWrapper.handleRuntimeError(e);
            }
        }
        
    }

    private ReflectMethod setMimeTypeStringMethod = new ReflectMethod(null, "setMimeType");

    /**
     * Gets the resource response's MIME type.
     *
     * @return The resource response's MIME type
     * @since 6.0
     */
    public String getMimeType() {
        try {
            return (String)getMimeTypeMethod.invoke();
        } catch (UnsupportedOperationException e) {
            if (coreWrapper == null) {
                throw new RuntimeException("Crosswalk's APIs are not ready yet");
            } else {
                XWalkCoreWrapper.handleRuntimeError(e);
            }
        }
        return null;
    }

    private ReflectMethod getMimeTypeMethod = new ReflectMethod(null, "getMimeType");

    /**
     * Sets the resource response's encoding, for example &quot;UTF-8&quot;. This is used
     * to decode the data from the input stream.
     *
     * @param encoding The resource response's encoding
     * @since 6.0
     */
    public void setEncoding(String encoding) {
        try {
            setEncodingStringMethod.invoke(encoding);
        } catch (UnsupportedOperationException e) {
            if (coreWrapper == null) {
                throw new RuntimeException("Crosswalk's APIs are not ready yet");
            } else {
                XWalkCoreWrapper.handleRuntimeError(e);
            }
        }
        
    }

    private ReflectMethod setEncodingStringMethod = new ReflectMethod(null, "setEncoding");

    /**
     * Gets the resource response's encoding.
     *
     * @return The resource response's encoding
     * @since 6.0
     */
    public String getEncoding() {
        try {
            return (String)getEncodingMethod.invoke();
        } catch (UnsupportedOperationException e) {
            if (coreWrapper == null) {
                throw new RuntimeException("Crosswalk's APIs are not ready yet");
            } else {
                XWalkCoreWrapper.handleRuntimeError(e);
            }
        }
        return null;
    }

    private ReflectMethod getEncodingMethod = new ReflectMethod(null, "getEncoding");

    /**
     * Sets the input stream that provides the resource response's data. Callers
     * must implement {@link InputStream#read(byte[]) InputStream.read(byte[])}.
     *
     * @param data the input stream that provides the resource response's data. Must not be a
     *             StringBufferInputStream.
     * @since 6.0
     */
    public void setData(InputStream data) {
        try {
            setDataInputStreamMethod.invoke(data);
        } catch (UnsupportedOperationException e) {
            if (coreWrapper == null) {
                throw new RuntimeException("Crosswalk's APIs are not ready yet");
            } else {
                XWalkCoreWrapper.handleRuntimeError(e);
            }
        }
        
    }

    private ReflectMethod setDataInputStreamMethod = new ReflectMethod(null, "setData");

    /**
     * Gets the input stream that provides the resource response's data.
     *
     * @return The input stream that provides the resource response's data
     * @since 6.0
     */
    public InputStream getData() {
        try {
            return (InputStream)getDataMethod.invoke();
        } catch (UnsupportedOperationException e) {
            if (coreWrapper == null) {
                throw new RuntimeException("Crosswalk's APIs are not ready yet");
            } else {
                XWalkCoreWrapper.handleRuntimeError(e);
            }
        }
        return null;
    }

    private ReflectMethod getDataMethod = new ReflectMethod(null, "getData");

    /**
     * Sets the resource response's status code and reason phrase.
     *
     * @param statusCode the status code needs to be in the ranges [100, 299], [400, 599].
     *                   Causing a redirect by specifying a 3xx code is not supported.
     * @param reasonPhrase the phrase describing the status code, for example "OK". Must be non-null
     *                     and not empty.
     * @since 6.0
     */
    public void setStatusCodeAndReasonPhrase(int statusCode, String reasonPhrase) {
        try {
            setStatusCodeAndReasonPhraseintStringMethod.invoke(statusCode, reasonPhrase);
        } catch (UnsupportedOperationException e) {
            if (coreWrapper == null) {
                throw new RuntimeException("Crosswalk's APIs are not ready yet");
            } else {
                XWalkCoreWrapper.handleRuntimeError(e);
            }
        }
        
    }

    private ReflectMethod setStatusCodeAndReasonPhraseintStringMethod = new ReflectMethod(null, "setStatusCodeAndReasonPhrase");

    /**
     * Gets the resource response's status code.
     *
     * @return The resource response's status code.
     * @since 6.0
     */
    public int getStatusCode() {
        try {
            return (Integer)getStatusCodeMethod.invoke();
        } catch (UnsupportedOperationException e) {
            if (coreWrapper == null) {
                throw new RuntimeException("Crosswalk's APIs are not ready yet");
            } else {
                XWalkCoreWrapper.handleRuntimeError(e);
            }
        }
        return 0;
    }

    private ReflectMethod getStatusCodeMethod = new ReflectMethod(null, "getStatusCode");

    /**
     * Gets the description of the resource response's status code.
     *
     * @return The description of the resource response's status code.
     * @since 6.0
     */
    public String getReasonPhrase() {
        try {
            return (String)getReasonPhraseMethod.invoke();
        } catch (UnsupportedOperationException e) {
            if (coreWrapper == null) {
                throw new RuntimeException("Crosswalk's APIs are not ready yet");
            } else {
                XWalkCoreWrapper.handleRuntimeError(e);
            }
        }
        return null;
    }

    private ReflectMethod getReasonPhraseMethod = new ReflectMethod(null, "getReasonPhrase");

    /**
     * Sets the headers for the resource response.
     *
     * @param headers Mapping of header name to header value.
     * @since 6.0
     */
    public void setResponseHeaders(Map<String, String> headers) {
        try {
            setResponseHeadersMapMethod.invoke(headers);
        } catch (UnsupportedOperationException e) {
            if (coreWrapper == null) {
                throw new RuntimeException("Crosswalk's APIs are not ready yet");
            } else {
                XWalkCoreWrapper.handleRuntimeError(e);
            }
        }
        
    }

    private ReflectMethod setResponseHeadersMapMethod = new ReflectMethod(null, "setResponseHeaders");

    /**
     * Gets the headers for the resource response.
     *
     * @return The headers for the resource response.
     * @since 6.0
     */
    public Map<String, String> getResponseHeaders() {
        try {
            return (Map<String, String>)getResponseHeadersMethod.invoke();
        } catch (UnsupportedOperationException e) {
            if (coreWrapper == null) {
                throw new RuntimeException("Crosswalk's APIs are not ready yet");
            } else {
                XWalkCoreWrapper.handleRuntimeError(e);
            }
        }
        return null;
    }

    private ReflectMethod getResponseHeadersMethod = new ReflectMethod(null, "getResponseHeaders");


    void reflectionInit() {
        XWalkCoreWrapper.initEmbeddedMode();

        coreWrapper = XWalkCoreWrapper.getInstance();
        if (coreWrapper == null) {
            XWalkCoreWrapper.reserveReflectObject(this);
            return;
        }

        setMimeTypeStringMethod.init(bridge, null,
                "setMimeTypeSuper", String.class);
        getMimeTypeMethod.init(bridge, null,
                "getMimeTypeSuper");
        setEncodingStringMethod.init(bridge, null,
                "setEncodingSuper", String.class);
        getEncodingMethod.init(bridge, null,
                "getEncodingSuper");
        setDataInputStreamMethod.init(bridge, null,
                "setDataSuper", InputStream.class);
        getDataMethod.init(bridge, null,
                "getDataSuper");
        setStatusCodeAndReasonPhraseintStringMethod.init(bridge, null,
                "setStatusCodeAndReasonPhraseSuper", int.class, String.class);
        getStatusCodeMethod.init(bridge, null,
                "getStatusCodeSuper");
        getReasonPhraseMethod.init(bridge, null,
                "getReasonPhraseSuper");
        setResponseHeadersMapMethod.init(bridge, null,
                "setResponseHeadersSuper", Map.class);
        getResponseHeadersMethod.init(bridge, null,
                "getResponseHeadersSuper");
    }

}
